<?php

/**
 * 处理和接收 HTTP 请求的内容
 *
 * @category   ORG
 * @package    ORG
 * @subpackage Auth
 * @author     海啸 <459103503@qq.com>
 */
class RestSign
{
    //获取配置信息
    private $_paramsAll;

    //认证Key
    private $_key;

    //请求来源
    private $_clientId;

    //认证密钥
    private $_secretKey;

    //认证类型
    private $_grantType;

    //服务器IP(数据发送方，指定的服务器)
    private $_ip;

    //获取的真实的IP
    private $_realIp;

    //当前时间精确到秒
    private $_r;

    //生成token
    private $_token;

    //过期时间
    private $_expireTime = 0;

    //是否开启认证
    private $_isAuth;

    //是否做IP认证
    private $_isIp;

    //是否做时间认证
    private $_isTime;

    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->_r = time();
        $this->_isAuth = true;
        $this->_isIp   = true;
        $this->_isTime = true;
    }

    /**
     * 获取认证参数
     *
     * @param array $params 认证参数
     *
     * @return RestAuth
     */
    public function setConfig($params)
    {
        $this->_paramsAll = $params;
        $this->_paramsAll['r'] = $this->_r;


        foreach ($this->_paramsAll as $key=>$value) {
            $param = '_'.$key;
            $this->$param = preg_replace("/\s/", "", $value);
        }

        return $this;
    }

    /**
     * 设置有效期
     *
     * @param int $expireTime 过期时间
     *
     * @return RestAuth
     */
    public function setExpireTime($expireTime)
    {
        $this->_expireTime = $expireTime;

        return $this;
    }
    /**
     * 设置认证参数
     *
     * @param string $key   数据的key
     * @param string $value 数据值
     *
     * @return RestAuth
     */
    public function setParam($key, $value)
    {
        $param = '_'.$key;
        if (property_exists($this, $param)) {
            $this->_paramsAll[$key] = $value;
            $this->$param = $value;
        }

        return $this;
    }

    /**
     * 生成sign认证串
     *
     * @return string
     */
    public function setSign()
    {
        //认证串
        $sign = '';
        //认证信息
        $authArr = array('grantType','clientId','secretKey','r');
        foreach ($this->_paramsAll as $k=>$v) {
            if (in_array($k, $authArr)) {
                $sign .=$k.':'.$v.',';
            }
        }
        $this->_token = trim($sign, ',');
        return 'token:'.md5($this->_token).','.'clientId:'.$this->_clientId.','.'r:'.$this->_r;
    }
    /**
     * 获取key值
     *
     * @return string
     */
    public function getKey()
    {
        return $this->_key;
    }

    /**
     * 拆分sign字串
     *
     * @param string $sign sign字串
     *
     * @return RestSign
     */
    public function exSign($sign)
    {
        //返回的认证串集
        $authSign = array();

        if (!strrpos($sign, ',') || !strrpos($sign, ':')) {
            return $this;
        }

        $signTmp = explode(',', $sign);

        foreach ($signTmp as $v) {
            $signArr = explode(':', $v);
            $authSign[$signArr[0]] = $signArr[1];
        }
        $this->_clientId = $authSign['clientId'];
        $this->_token    = $authSign['token'];
        $this->_r        = $authSign['r'];

        return $this;
    }

    /**
     * 获取来源配置
     *
     * @param array $sConfig 站点配置
     *
     * @return RestSign
     */
    public function setSitesAuth($sConfig)
    {

        $this->setConfig($sConfig[$this->_clientId]);

        return $this;
    }

    /**
     * 获取真实的IP
     *
     * @param string $realIp 真实IP
     *
     * @return RestSign
     */
    public function setRealIp($realIp)
    {
        $this->_realIp = $realIp;

        return $this;
    }

    /**
     * 认证
     *
     * @return bool
     */
    public function auth()
    {
        //判断是否要做安全认证
        if (!$this->_isAuth) {
            return true;
        }
        //时间差
        $timeDiff = (int)(time()-$this->_r);

        //判断是否要做IP认证
        if ($this->_isIp) {

            //ip集
            $ips= stripos($this->_ip, ',') ? explode(',', $this->_ip) : array($this->_ip);

            //判断IP是否匹配
            if (!in_array($this->_realIp, $ips)) {
                return false;
            }
        }

        //判断是否要做时间段认证
        if ($this->_isTime) {
            //判断是否失效
            if ($timeDiff<0 || $timeDiff>$this->_expireTime) {
                return false;
            }
        }

        //判断token是否有效
        $token = $this->_createToken();
        if (strcasecmp($this->_token, $token) !=0) {
            return false;
        }

        return true;

    }

    /**
     * 生成认证token
     *
     * @return string
     */
    private function _createToken()
    {
        //认证信息
        $authArr = array('grantType','clientId','secretKey','r');
        //获取token
        $token = '';
        foreach ($this->_paramsAll as $k=>$v) {
            if (in_array($k, $authArr)) {
                $token .=$k.':'.$v.',';
            }
        }
        return md5(trim($token, ','));

    }










}